#ifndef __INCLUDED_CBL_MATRIX_H__
#error "CBL_MatrixTypes.hpp must not be used directly. Use CBL_Matrix.h instead."
#else
#ifndef __INCLUDED_CBL_MATRIX_TYPES_HPP__
#define __INCLUDED_CBL_MATRIX_TYPES_HPP__

// ---------------------------------------------------------------------------------------------------------------------
//	This file defines convinience classes, derived from CMatrix.
//	Classes defined here contain per-element accessors.
//	Types like Float4x4 are based on these classes here.
// ---------------------------------------------------------------------------------------------------------------------

#define ACCESSOR(_MJ,_MN)		CB_FORCEINLINE TType& CB_INLINE_ATTR M##_MJ##_MN()				{ return (*this)[_MJ][_MN]; } \
								CB_FORCEINLINE const TType& CB_INLINE_ATTR M##_MJ##_MN() const	{ return (*this)[_MJ][_MN]; }

// -------------------------------------------------------------------------------------------------

template <typename TType>
class CMatrix22 : public CMatrix<TType, 2,2>
{
public:
	
	CMatrix22() : CMatrix<TType,2,2>() {}
	
	CMatrix22(const TType* _pData) : CMatrix<TType,2,2>(_pData) {}
	
	template <typename TType2, uint32 TMajorSize2, uint32 TMinorSize2>
	CMatrix22(const CMatrix<TType2, TMajorSize2, TMinorSize2>& _rOther) : CMatrix<TType,2,2>(_rOther) {}
	
	CMatrix22(	const TType& _rM00, const TType& _rM01,
				const TType& _rM10, const TType& _rM11) 
	{
		(*this)[0][0] = _rM00; (*this)[0][1] = _rM01;
		(*this)[1][0] = _rM10; (*this)[1][1] = _rM11;
	}
	
public:
	ACCESSOR(0,0)
	ACCESSOR(0,1)
	
	ACCESSOR(1,0)
	ACCESSOR(1,1)
};

// -------------------------------------------------------------------------------------------------

template <typename TType>
class CMatrix33 : public CMatrix<TType, 3,3>
{
public:
	
	CMatrix33() : CMatrix<TType,3,3>() {}
	
	CMatrix33(const TType* _pData) : CMatrix<TType,3,3>(_pData) {}
	
	template <typename TType2, uint32 TMajorSize2, uint32 TMinorSize2>
	CMatrix33(const CMatrix<TType2, TMajorSize2, TMinorSize2>& _rOther) : CMatrix<TType,3,3>(_rOther) {}
	
	CMatrix33(	const TType& _rM00, const TType& _rM01, const TType& _rM02,
				const TType& _rM10, const TType& _rM11, const TType& _rM12,
				const TType& _rM20, const TType& _rM21, const TType& _rM22) 
	{
		(*this)[0][0] = _rM00; (*this)[0][1] = _rM01; (*this)[0][2] = _rM02;
		(*this)[1][0] = _rM10; (*this)[1][1] = _rM11; (*this)[1][2] = _rM12;
		(*this)[2][0] = _rM20; (*this)[2][1] = _rM21; (*this)[2][2] = _rM22;
	}
	
public:
	ACCESSOR(0,0)
	ACCESSOR(0,1)
	ACCESSOR(0,2)
	
	ACCESSOR(1,0)
	ACCESSOR(1,1)
	ACCESSOR(1,2)
	
	ACCESSOR(2,0)
	ACCESSOR(2,1)
	ACCESSOR(2,2)
};

// -------------------------------------------------------------------------------------------------

template <typename TType>
class CMatrix44 : public CMatrix<TType, 4,4>
{
public:
	
	CMatrix44() : CMatrix<TType,4,4>() {}
	
	CMatrix44(const TType* _pData) : CMatrix<TType,4,4>(_pData) {}
	
	template <typename TType2, uint32 TMajorSize2, uint32 TMinorSize2>
	CMatrix44(const CMatrix<TType2, TMajorSize2, TMinorSize2>& _rOther) : CMatrix<TType,4,4>(_rOther) {}
	
	CMatrix44(	const TType& _rM00, const TType& _rM01, const TType& _rM02, const TType& _rM03,
				const TType& _rM10, const TType& _rM11, const TType& _rM12, const TType& _rM13,
				const TType& _rM20, const TType& _rM21, const TType& _rM22, const TType& _rM23,
				const TType& _rM30, const TType& _rM31, const TType& _rM32, const TType& _rM33) 
	{
		(*this)[0][0] = _rM00; (*this)[0][1] = _rM01; (*this)[0][2] = _rM02; (*this)[0][3] = _rM03;
		(*this)[1][0] = _rM10; (*this)[1][1] = _rM11; (*this)[1][2] = _rM12; (*this)[1][3] = _rM13;
		(*this)[2][0] = _rM20; (*this)[2][1] = _rM21; (*this)[2][2] = _rM22; (*this)[2][3] = _rM23;
		(*this)[3][0] = _rM30; (*this)[3][1] = _rM31; (*this)[3][2] = _rM32; (*this)[3][3] = _rM33;
	}
	
public:
	
	ACCESSOR(0,0)
	ACCESSOR(0,1)
	ACCESSOR(0,2)
	ACCESSOR(0,3)
	
	ACCESSOR(1,0)
	ACCESSOR(1,1)
	ACCESSOR(1,2)
	ACCESSOR(1,3)
	
	ACCESSOR(2,0)
	ACCESSOR(2,1)
	ACCESSOR(2,2)
	ACCESSOR(2,3)
	
	ACCESSOR(3,0)
	ACCESSOR(3,1)
	ACCESSOR(3,2)
	ACCESSOR(3,3)
};

#endif
#endif